package MeshlessShapeFunctions;

import java.util.ArrayList;

import jmeshless.NewOkCancelDialog;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import HashMatrix2.HashMatrix2;
import HashMatrix2.LUFactorization;

public class test {
	public static ArrayList<Particle> nodes = new ArrayList<Particle>();
	public static int PolinomialDegree = 1;
	
	
	
	public static ArrayList<Double> getBaseVector(double xi){
        ArrayList<Double> L = new ArrayList<Double>();
        for (int i = 0; i <= PolinomialDegree; i++) {
            L.add(Math.pow((xi), i));
        }
//        L.add((Math.sin(5*xi)));
        L.add((Math.exp(50*xi)));
        return L;
    }
	
	
	
	public static double calc(double x, int n){
		double res = 0.0;
		
		HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, getBaseVector(0.0).size());
		double[] b = new double[getBaseVector(0.0).size()];
		
		for (int i = 0; i < nodes.size(); i++) {
			Particle p = nodes.get(i);
			ArrayList<Double> L = getBaseVector(p.x);
			double val = JStKernel.evaluate(x, p.x, p.rho);
			
			for (int j = 0; j < L.size(); j++) {
				for (int k = 0; k < L.size(); k++) {
					A.setValue(j, k, A.getValue(j, k)+ val*L.get(j)*L.get(k));
				}
			}
		}
		
		ArrayList<Double> L = getBaseVector(nodes.get(n).x);
		
		for (int i = 0; i < b.length; i++) {
			b[i] = L.get(i)*JStKernel.evaluate(x, nodes.get(n).x, nodes.get(n).rho);
		}
		
		LUFactorization lu = new LUFactorization(A);
		
		double[] r = lu.calculate(b);
		
		
		L = getBaseVector(x);
		
		for (int i = 0; i < r.length; i++) {
			res+=L.get(i)*r[i];
		}
		
		return res;
	}
	
	public static void main(String[] args) {
		double a = 0.0,b=1;
        


        int nn = 10;
//        double h = (b-a)/(double)nn;
//        for (int i = 0; i <=nn; i++) {
//        	nodes.add(new Particle(a+h*i, 0, i));
//        }
//        
//        for (int i = 0; i < nodes.size(); i++) {
//        	Particle particle = nodes.get(i);
//        	double rho = (1.1+0.5*(i+1))*h;
////        	rho = (1.1 )*h;
//        	particle.setRho(rho);
//        }
        double rho = 0.0;
        
        nodes.add( new Particle(0.0 , 0,0 ));
        rho  = 0.1*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.05 , 0,1 ));
        rho  = 0.1*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.1 , 0,2 ));
        rho  = 0.15*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.25 , 0,3 ));
        rho  = 0.25*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.5 , 0,4 ));
        rho  = 0.25*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.75 , 0,5 ));
        rho  = 0.25*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.9, 0,6 ));
        rho  = 0.15*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(0.95 , 0,7 ));
        rho  = 0.1*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        nodes.add( new Particle(1.0 , 0,8 ));
        rho  = 0.1*2.1;
        nodes.get(nodes.size()-1).setRho(rho);
        
        XYSeriesCollection col  = new XYSeriesCollection();
        
        for (int i = 0; i < nodes.size(); i++) {
        	double x = a;
        	XYSeries series1 = new XYSeries("func", true, true);
            while(x<b+0.00001){
                double tmp2 = calc(x,i);
//                System.out.print(x+"\t"+tmp2+"\n");
                series1.add(x,tmp2);
                x+=0.0001;
            }
            col.addSeries(series1);
		}
        
        
        

        NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        
        HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, nodes.size());
        double[] B = new double[A.getN()];
            for (int i = 0; i < nodes.size(); i++) {
                for (int j = 0; j < nodes.size(); j++) {
                	double x = nodes.get(j).x;
                    A.setValue(j, i, calc(x,i));
                }
//                B[i] = Math.sin(5*nodes.get(i).x);
                B[i] = (1.0 / (Math.exp(50) - 1) * (1- Math.exp(50*nodes.get(i).x)) + nodes.get(i).x);
        }

        LUFactorization lu = new LUFactorization(A);
        double[] res = lu.calculate(B);
        
        XYSeries series1 = new XYSeries("approx", true, true);
        double x=a;
         while(x<b+0.0001){
            double tmp2 = 0.0;
            for (int j = 0; j <nodes.size(); j++) {
                tmp2+= calc(x,j)*res[j];
            }
            System.out.print(x+"\t"+tmp2+"\n");
            series1.add(x,tmp2);
            x+=0.01;
        }
         dialog = new NewOkCancelDialog(null, false, new  XYSeriesCollection(series1));
         dialog.setLocationRelativeTo(null);
         dialog.setVisible(true);
      
	}

}
